package com.swh.cloud.biz.ui.action;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang3.builder.ReflectionToStringBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.client.ServiceInstance;
import org.springframework.cloud.client.loadbalancer.LoadBalancerClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import org.springframework.cloud.netflix.ribbon.RibbonClients;
import org.springframework.cloud.netflix.ribbon.SpringClientFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestClientException;
import org.springframework.web.client.RestTemplate;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.swh.user.domain.UserEntity;

/**
 * 业务的请求处理（可加一些调用前的校验,提高请求的有效性），调用其他服务
 * @author sangwenhao
 * @date 2016年12月23日
 */
@Service
//name:服务端服务器注册的名称，configuration：对应的ribbon配置文件
@RibbonClient(name="myclientDefault")
//@RibbonClients(defaultConfiguration=BIZServerLBConfig.class)
//@RibbonClients({
//	@RibbonClient(name = "myclient" , configuration = BIZServerLBConfig.class)
//})//多个ribbonclient
public class UserServer {

    @Autowired
    private RestTemplate restTemplate ;
    
    @Autowired
    private SpringClientFactory clientFactory;
    
    @Autowired
    private LoadBalancerClient loadBalancerClient;
    
    private static final Logger logger = LoggerFactory.getLogger(UserServer.class);
    
    //这个服务名称就是在服务提供端user-cloud-biz-server中spring.application.name所配置的名字，
    //这个名字在服务启动时连同它的IP和端口号都注册到了EurekaServer
//    private final String SERVICE_NAME = "user-cloud-biz-server" ;
    private final String SERVICE_NAME = "user-cloud-biz-service" ;
    
    private final String URL = "http://"+SERVICE_NAME ;
    
    //断路器 @HystrixCommand注解的方法失败后，系统将自动切换到fallbackMethod方法执行
    //断路器Hystrix具备回退机制、请求缓存和请求打包以及监控和配置等功能
    //这里用的是 回退机制
    //注意fallbackMethod的方法要对应的方法的入参和出参类型一致
    //@HystrixCommand(groupKey="UserServer", commandKey = "getUserInfo")//可自定义（groupKey不同分组里对应不同的线程池）
    @HystrixCommand(fallbackMethod = "fallbackGetUserInfo",groupKey="biz-ui-getUserInfo")
    public UserEntity getUserInfo(Long id) {
    	  UserEntity userEntity;
		try {
			ServiceInstance serviceInstance = this.loadBalancerClient.choose("myclientDefault");
			  System.out.println("===" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort()
			      +";URI:"+serviceInstance.getUri());
			userEntity = restTemplate.getForObject(URL+"/userService/getUserInfo/"+id , UserEntity.class);
			logger.info("biz-ui 层接收到的内容："+ReflectionToStringBuilder.toString(userEntity));
			return userEntity ;
		} catch (Exception e) {
			logger.info("biz-ui 层接收到的内容 出错 ");
			e.printStackTrace();
		}
		return null ;
    }

    @HystrixCommand(fallbackMethod = "fallbackGetUserByUnion",groupKey="biz-ui-getUserByUnion")
    @SuppressWarnings("unchecked")
    public List<UserEntity> getUserByUnion(Map<String, UserEntity> paraMap){
	List<UserEntity> lists = null ;
	try {
		 ServiceInstance serviceInstance = this.loadBalancerClient.choose("myclientDefault");
         System.out.println("===" + serviceInstance.getServiceId() + ":" + serviceInstance.getHost() + ":" + serviceInstance.getPort()
   	      +";URI:"+serviceInstance.getUri());
         
    	  Map<String, UserEntity> map = new HashMap<String, UserEntity>();
          UserEntity userEntity = new UserEntity();
    	  userEntity.setUserName("admin");
    	  map.put("user1", userEntity);
//    	  restTemplate.setRequestFactory(new HttpComponentsClientHttpRequestFactory());
    	  lists = restTemplate.getForObject(URL+"/userService/getUserByUnion", List.class, map) ;
	} catch (Exception e) {
	    // TODO Auto-generated catch block
	    e.printStackTrace();
	    throw new NullPointerException();
	}
	return lists ;
    }
    
    //回退方法
    @SuppressWarnings("unused")
    private UserEntity fallbackGetUserInfo(Long id) {
	 logger.info(">>>>>>>> UserServer >>>>HystrixCommand fallbackMethod(fallbackGetUserInfo) handle!");
	 UserEntity user = new UserEntity();
	 user.setUserName("TestHystrixCommand->UserServer");
	 return user;
    }
    
    private List<UserEntity> fallbackGetUserByUnion(Map<String, UserEntity> paraMap){
	logger.info(">>>>>>>> UserServer >>>>HystrixCommand fallbackMethod(fallbackGetUserByUnion) handle!");
	List<UserEntity> ls = new ArrayList<UserEntity>();
	 UserEntity user = new UserEntity();
	 user.setUserName("TestHystrixCommand");
	 ls.add(user);
	 return ls;
    }
    
}
